﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace WooCoo.DataPortal.Client
{
    /// <summary>
    /// 过滤条件表达式
    /// </summary>
    public class FilterQueryOptionExpression : QueryOptionExpression
    {
        /// <summary>
        /// The individual expressions that makes the filter predicate
        /// </summary>
        private readonly List<Expression> individualExpressions;

        public override ExpressionType NodeType
        {
            get
            {
                return (ExpressionType)ResourceExpressionType.FilterQueryOption;
            }
        }
        /// <summary>predicate</summary>
        private Expression predicate;

        /// <summary>
        /// Gets the list of individual conjucts which are separated by AND for the predicate
        /// i.e. if the filter statement is id1=1 and id2="foo" and id3=datetime'31'
        /// then this list will have 3 entries, id1=1, id2="foo" and id3=datetime'xxxxxxxxx'
        /// </summary>
        internal ReadOnlyCollection<Expression> PredicateConjuncts
        {
            get
            {
                return new ReadOnlyCollection<Expression>(this.individualExpressions);
            }
        }

        /// <summary>
        /// Creates a FilterQueryOptionExpression expression
        /// </summary>
        /// <param name="type">the return type of the expression</param>
        /// <param name="predicate">the predicate</param>
        public FilterQueryOptionExpression(Type type)
            : base(type)
        {
            this.individualExpressions = new List<Expression>();
        }

        /// <summary>
        /// Adds the conjuncts to individualExpressions
        /// </summary>
        /// <param name="predicates">The predicates.</param>
        public void AddPredicateConjuncts(IEnumerable<Expression> predicates)
        {
            this.individualExpressions.AddRange(predicates);
        }
        /// <summary>
        /// Gets the query option value.
        /// </summary>
        /// <returns>A predicate with all Conjuncts AND'ed</returns>
        public Expression GetPredicate()
        {
            Expression expression = null;
            bool flag = true;
            foreach (Expression current in this.individualExpressions)
            {
                if (flag)
                {
                    expression = current;
                    flag = false;
                }
                else
                {
                    expression = Expression.And(expression, current);
                }
            }
            return expression;
        }
    }
}
